import Axios from 'axios';
import {
  error
} from 'shelljs';
import config from '../config/config.js'
import {
  getToken
} from './auth.js'

// 定义config对象
let {
  HTTP_REQUEST_URL,
  WSS_SERVER_URL,
  HEADER,
  SERVER_DEBUG,
  PING_INTERVAL,
  TOKEN_NAME,
  TOKEN_FORMAT,
  CACHE_USERINFO,
  CACHE_TOKEN,
  CACHE_EXPIRES_TIME
} = config;

// 缓存存储格式：get和post请求数据单独分为两个对象，分别存储url+params的拼接结果作为key值，缓存值作为value
const cache = {
  get: {},
  post: {}
};

// 创建一个 axios 实例
const INSTANCE = Axios.create({
  baseURL: HTTP_REQUEST_URL, // 公共的接口地址
  timeout: 50000, // 请求超时时间设置
  withCredentials: true //跨域时使用凭证，默认带上cookies
});

// 请求拦截器，config 是发送请求的参数信息
INSTANCE.interceptors.request.use(
  config => {
    // 是否请求需要带上 token
    if (!config.noToken) {
      config.headers[TOKEN_NAME] = TOKEN_FORMAT(getToken(CACHE_TOKEN));
      return config;
    }
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
);

// 响应拦截器，response为响应的结构组织，包括data，headers，status，statusText，config，request
INSTANCE.interceptors.response.use(
  response => {
    // 后台返回数据
    const data = response.data;
    // 这个状态码和提示信息是和后端约定的
    const {
      code,
      msg
    } = data
    // 根据 code 进行判断，与后端约定某些状态该返回什么数据
    switch (code) {
      // 如果没有 code，可能后端返回的数据不是json类型，直接返回响应结构
      case undefined:
        return response;
        //code === 200 代表没有错误，这里的状态 200 是与后端协商的成功状态码
      case 200:
        return data;
        // 举例：token已过期的code报错，需要返回登录页重新登录！与后端约定20003为token过期状态！
      case 20003:
        errorCreate(`token已过期，请重新登录`);
        // 跳转登录页，清除登录信息！
        break;
        // 其他 code，抛出错误提示信息
      default:
        errorCreate(`[ code: ${code}] ${msg}`);
        return data;
    }
  },
  error => {
    if (error && error.response) {
      switch (error.response.status) {
        case 400:
          error.message = '请求错误';
          break
        case 401:
          error.message = '未授权，请登录', reLogin();
          break
        case 403:
          error.message = '拒绝访问';
          break
        case 404:
          error.message = `请求地址错误: ${error.response.config.url}`;
          break
        case 408:
          error.message = '请求超时';
          break
        case 500:
          error.message = '服务器内部错误';
          break
        case 501:
          error.message = '服务未实现';
          break
        case 502:
          error.message = '网关错误';
          break
        case 503:
          error.message = '服务不可用';
          break
        case 504:
          error.message = '网关超时';
          break
        case 505:
          error.message = 'HTTP版本不受支持';
          break
        default:
          error.message = '其他未知错误';
          break
      }
    }
    errorLog(error)
    return Promise.reject(error)
  }
);

// 对象key值排序
function objKeySort() {

}

